
import * as os from "node:os";
import { FirewallProfile, FirewallProfileType, FirewallStatusTypeMap, NetIf, RouteConf } from "../type/interfaces.ts";
import {hasIPv4Address, runCmd, sleep} from "../vendor/utils.ts";
import {electronLogger} from "../vendor/electron-logger.ts";

export default class NetService {

  private netIfs: NetIf[] = [];

  showRouteTable(): RouteConf[] {
    const routeOutput = runCmd('route print -4')
    const list: RouteConf[] = []

    if (this.netIfs.length == 0) {
      this.getNetIfs()
    }
    routeOutput.split('\r\n').map(line => {
      if (!hasIPv4Address(line)) {
        return
      }
      // 清理多余空格并分割字段
      const cleaned = line.replace(/\s+/g, ' ').trim();
      const parts = cleaned.split(/\s+/);
      if (parts.length < 5) {
        return
      }
      const netIf = this.getNetIfByIp(parts[3])
      const route: RouteConf = {
        destination: parts[0],
        mask: parts[1],
        gateway: parts[2],
        ip: parts[3],
        metric: parts[4],
        ifIndex: netIf.ifIndex,
      };
      list.push(route)
    })

    return list

  }

  deleteRoute(data:RouteConf){
    if (data.gateway == "在链路上") {
      data.gateway = data.ip
    }
    runCmd(`route DELETE ${data.destination} mask ${data.mask} ${data.gateway}`)
  }

  changeRoute(type:string, data:RouteConf){
    //route change 10.8.0.23 mask 255.255.255.255 10.8.0.1 METRIC 1 if 50
    const cmd = `route ${type} ${data.destination} mask ${data.mask} ${data.gateway} METRIC ${data.metric} if ${data.ifIndex} && timeout /t 1`
    electronLogger.info(cmd)
    const out = runCmd(cmd)
    electronLogger.info("changeRoute:" + out)
  }



  // 获取所有网卡
  getNetIfs():NetIf[] {
    // 获取网卡跃点数
    const metricMap: Record<string, string> = {}
    const output = runCmd(`powershell.exe "Get-NetIPInterface -AddressFamily IPv4 | Select-Object ifIndex,InterfaceMetric | ConvertTo-Csv -NoTypeInformation"`);
    output.split('\r\n').slice(1).map(line=>{
      const arr = line.split(',').map(f => f.trim().replace(/"/g, ''));
      if (arr.length != 2) {
        return
      }
      metricMap[arr[0]] = arr[1];
    })

    this.netIfs = []
    // 获取网卡ip信息
    const list = os.networkInterfaces()
    // 获取网卡信息
    const str = runCmd(`powershell.exe "Get-NetAdapter | Select-Object Name,InterfaceDescription, MacAddress, ifIndex,Status, LinkSpeed | ConvertTo-Csv -NoTypeInformation"`)
    str.split('\r\n').slice(1).map(line => {

      const arr = line.split(',').map(f => f.trim().replace(/"/g, ''));
      if (arr.length != 6) {
        return
      }
      const info: NetIf = {
        name: arr[0],
        desc: arr[1],
        mac: arr[2],
        ifIndex: arr[3],
        status: arr[4],
        speed: arr[5],
        ipv4: "",
        metric:metricMap[arr[3]] || "",
      };
      const osInfo = list[info.name]
      if (osInfo) {
        osInfo.map((v) => {
          if (v.family == "IPv4") {
            info.ipv4 = v.address
          }
        })
      }
      this.netIfs.push(info)
    });
    return this.netIfs
  }


  getNetIfById(id: string): NetIf {
    for (const network of this.netIfs) {
      if (network.ifIndex == id) return network;
    }
    return {
      desc: "",
      ifIndex: "",
      ipv4: "",
      mac: "",
      metric: "",
      name: "",
      restarting: false,
      speed: "",
      status: "",
      toggling: false
    };
  }

  getNetIfByIp(ip: string): NetIf {
    for (const network of this.netIfs) {
      if (network.ipv4 == ip) return network;
    }
    return {
      desc: "",
      ifIndex: "",
      ipv4: "",
      mac: "",
      metric: "",
      name: "",
      restarting: false,
      speed: "",
      status: "",
      toggling: false
    };
  }

  getFirewallStatus(): FirewallProfile[] {

    const output = runCmd('netsh advfirewall show allprofiles state');
    const lines = output.split('\r\n');
    const result: FirewallProfile[] = [];

    let currentProfile = '';
    lines.forEach(line => {
      if (line.includes('配置文件 设置:')) {
        currentProfile = line.split('配置文件')[0].trim();
      } else if (line.includes('状态') && currentProfile) {
        result.push({
          profile: `${currentProfile}`,
          state: line.includes('启用')
        });
      }
    });
    return result;

  }

  setFirewallStatus(status: boolean, profile?: FirewallProfileType) {
    let ftype: string;
    if (profile) {
      ftype = FirewallStatusTypeMap[profile];
    } else {
      ftype = 'all';
    }
    runCmd(`netsh advfirewall set ${ftype}profile state ${status ? 'on' : 'off'}`);
  }

  async restartNetworkAdapter(name: string) {
    this.setNetworkAdapterStatus(name, false)
    await sleep(1000)
    this.setNetworkAdapterStatus(name, true)
  }

  setNetworkAdapterStatus(name: string, enable: boolean) {
    runCmd(`netsh interface set interface "${name}" admin=${enable ? 'enable' : 'disable'}`)
  }
}


export let netService = new NetService()